<?php


namespace app\api\controller\v1;


use app\common\controller\Api;
use think\Db;
use think\Exception;

/**
 * 兼职接口
 * Class Job
 */
class Job extends Api
{

    protected $noNeedLogin = ['indexJob', 'search', 'date'];
    protected $noNeedRight = '*';

    public static $job_type = [1 => '半天岗', 2 => '全天岗', 3 => '节假岗', 4 => '小时岗'];
    public static $status = [1 => '未发布', 2 => '报名中', 3 => '进行中', 4 => '已完成', 5 => '已下线'];

    protected function _initialize()
    {
        parent::_initialize();
    }


    /**
     * 首页兼职列表
     * 最近七天的兼职信息
     */
    public function indexJob()
    {
        if ($this->request->isGet()) {

            $city_name = $this->request->param('city', false);
            $city_name == false && $this->error('city 参数不得为空');

            // 查找城市
            $city_id = Db::name('area')->where(['name' => $city_name])->find();
            !$city_id && $this->error('未找到 city 参数对应的城市ID');

            $today = date('Y-m-d');
            $seven = date('Y-m-d', strtotime('+7 day'));


            $result = Db::name('job')
                        ->whereTime('job_date', 'between', [$today, $seven])
                        ->group('job_date')
                        ->field('job_date,count(job_date) as jobs')
                        ->where(['status' => ['in',"2,3"], 'city_id' => $city_id['id']])
                        ->where('job_people > job_number')
                        ->select();

            for ($i = 0; $i < 7; $i++) {
                if (isset($result[$i])) {
                    $result[$i]['week']     = $this->getWeek($result[$i]['job_date']);
                    $result[$i]['month']    = date('m', strtotime($result[$i]['job_date']));
                    $result[$i]['today']    = date('d', strtotime($result[$i]['job_date']));
                    $result[$i]['is_today'] = $result[$i]['job_date'] === $today;
                    $result[$i]['year']     = date('Y', strtotime($result[$i]['job_date']));
                } else {
                    if ($i == 0) {
                        $this_date = date('Y-m-d', time());
                    } else {
                        $this_date = date('Y-m-d', strtotime($result[$i - 1]['job_date']) + 3600 * 24);
                    }
                    $result[$i] = [
                        'job_date' => $this_date,
                        'jobs'     => 0,
                        'week'     => $this->getWeek($this_date),
                        'month'    => date('m', strtotime($this_date)),
                        'today'    => date('d', strtotime($this_date)),
                        'is_today' => $this_date === $today,
                        'year'     => date('Y', strtotime($this_date)),
                    ];
                }
            }

            $this->success('获取成功', $result);
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 搜索酒店列表
     */
    public function search()
    {
        if ($this->request->isGet()) {

            $today = date('Y-m-d');
            $seven = date('Y-m-d', strtotime('+7 day'));

            if ($this->auth->isLogin()) {
                $company_id = $this->auth->company_id;
            } else {
                $company_id = 0;
            }

            $key       = $this->request->param('key', false);
            $city_name = $this->request->param('city', false);

            $city_name == false && $this->error('city 参数不得为空');
            $key == false && $this->error('key 参数不得为空');

            // 查找城市
            $city_id = Db::name('area')->where(['name' => $city_name])->find();
            !$city_id && $this->error('未找到 city 参数对应的城市ID');

            $query = Db::name('hotel')
                       ->alias('h')
                       ->join('job j', 'h.id = j.hotel_id', 'left')
                       ->whereLike('h.hotel_name', '%' . $key . '%')
                       ->where(['h.status' => 1, 'j.status' => ['in',"2,3"], 'j.city_id' => $city_id['id']])
                       ->where('j.job_people > j.job_number')
                       ->where('j.job_date', 'between', [$today, $seven])
                       ->group('h.id')
                       ->order('speed', 'desc')
                       ->field("h.id as hotel_id,h.hotel_name,sum(j.job_people) as sum,sum(job_number) as now, sum(job_number)/sum(j.job_people) as speed, j.job_location,if(j.job_company_group_id = $company_id,100,1) * (sum(job_number)/sum(j.job_people)) as weight")
                       ->buildSql();

            $result = Db::table($query . 'data')
                        ->order('data.weight', 'desc')
                        ->paginate(null, false, $this->paginate)
                        ->each(function ($item) use ($city_id, $key, $today, $seven) {
                            $find = Db::name('hotel')
                                      ->alias('h')
                                      ->join('job j', 'h.id = j.hotel_id', 'left')
                                      ->whereLike('h.hotel_name', '%' . $key . '%')
                                      ->where(['h.status' => 1, 'j.status' => 2, 'j.city_id' => $city_id['id']])
                                      ->where('j.job_people > j.job_number')
                                      ->where('j.job_date', 'between', [$today, $seven])
                                      ->where(['j.hotel_id' => $item['hotel_id']])
                                      ->order('speed', 'desc')
                                      ->field("j.id,j.job_type as type,j.job_price as price,j.job_people as sum,job_number as now,job_number/j.job_people as speed")
                                      ->select();
                            foreach ($find as &$i) {
                                $i['type_text'] = self::$job_type[$i['type']];
                                $i['speed']     = intval($i['now'] / $i['sum'] * 100) . '%';
                            }
                            $item['speed'] = intval($item['now'] / $item['sum'] * 100) . '%';
                            $item['data']  = $find;
                            unset($item['weight']);
                            return $item;
                        });

            if ($result->toArray()['data'] == null) {
                $this->success('暂无数据', $result, 2);
            } else {
                $this->success('获取成功', $result);
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 按照日期获取酒店的兼职列表
     */
    public function date()
    {
        if ($this->request->isGet()) {

            if ($this->auth->isLogin()) {
                $company_id = $this->auth->company_id;
            } else {
                $company_id = 0;
            }
            $date      = $this->request->param('date', false);
            $city_name = $this->request->param('city', false);

            $date == false && $this->error('date 参数不能为空');
            $city_name == false && $this->error('city 参数不得为空');
            !strtotime($date) && $this->error('日期格式不正确');

            // 查找城市
            $city_id = Db::name('area')->where(['name' => $city_name])->find();
            !$city_id && $this->error('未找到 city 参数对应的城市ID');

            $query = Db::name('hotel')
                       ->alias('h')
                       ->join('job j', 'h.id = j.hotel_id', 'left')
                       ->where(['h.status' => 1, 'j.status' => ['in',"2,3"], 'j.city_id' => $city_id['id']])
                       ->where('j.job_date', '=', $date)
                       ->where('j.job_people > j.job_number')
                       ->group('h.id')
                       ->order('speed', 'desc')
                       ->field("h.id as hotel_id,h.hotel_name,sum(j.job_people) as sum,sum(job_number) as now, sum(job_number)/sum(j.job_people) as speed, j.job_location,if(j.job_company_group_id = $company_id,100,1) * (sum(job_number)/sum(j.job_people)) as weight")
                       ->buildSql();

            $result = Db::table($query . 'data')
                        ->order('data.weight', 'desc')
                        ->paginate(null, false, $this->paginate)
                        ->each(function ($item) use ($city_id, $date) {
                            $find = Db::name('hotel')
                                      ->alias('h')
                                      ->join('job j', 'h.id = j.hotel_id', 'left')
                                      ->where(['h.status' => 1, 'j.status' => 2, 'j.city_id' => $city_id['id']])
                                      ->where('j.job_date', '=', $date)
                                      ->where('j.job_people > j.job_number')
                                      ->where(['j.hotel_id' => $item['hotel_id']])
                                      ->order('speed', 'desc')
                                      ->field("j.id,j.job_type as type,j.job_price as price,j.job_people as sum,job_number as now,job_number/j.job_people as speed")
                                      ->select();
                            foreach ($find as &$i) {
                                $i['type_text'] = self::$job_type[$i['type']];
                                $i['speed']     = intval($i['now'] / $i['sum'] * 100) . '%';
                            }
                            $item['speed'] = intval($item['now'] / $item['sum'] * 100) . '%';
                            $item['data']  = $find;
                            unset($item['weight']);
                            return $item;
                        });

            $this->success('获取成功', $result);
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 获取酒店下指定日期的兼职列表
     */
    public function child()
    {
        if ($this->request->isGet()) {

            $id   = $this->request->param('id', false);
            $date = $this->request->param('date', false);
            $id == false && $this->error('id 参数不得为空');
            $date == false && $this->error('date 参数不得为空');
            !strtotime($date) && $this->error('日期格式不正确');

            $result = Db::name('job')
                        ->where(['status' => 2, 'job_date' => $date])
                        ->where(['hotel_id' => $id])
                        ->field('id,job_type as type,job_people as sum,job_number as now,job_price as price')
                        ->paginate(false, null, $this->paginate)
                        ->each(function ($item) {
                            $item['type'] = self::$job_type[$item['type']];
                            return $item;
                        });

            $this->success('获取成功', $result);
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 兼职详情
     */
    public function details()
    {
        if ($this->request->isGet()) {

            $id = $this->request->param('id', false);
            $id == false && $this->error('id 参数不得为空');

            $result = Db::name('job')
                        ->alias('j')
                        ->join('hotel', 'hotel.id = j.hotel_id', 'left')
                        ->where(['j.status' => 2, 'j.id' => $id])
                        ->field('j.id,j.job_type as type,j.job_company_id as company_id,hotel.hotel_name,j.job_location as location,j.job_people as sum,j.job_number as now,j.job_price as price,j.job_arrival_datetime as arrival,j.job_route as route,j.job_condition as `condition`,j.job_hotel_introduce as introduce,j.job_hotel_introduce as content')
                        ->find();

            $find = Db::name('order')
                      ->where(['user_id' => $this->auth->id, 'job_id' => $id])
                      ->find();

            $result['order_id'] = 0;
            $result['surplus'] = $result['sum'] - $result['now'];
            $result['type']    = self::$job_type[$result['type']];
            $result['real']    = $this->auth->real;
            $result['speed']   = intval($result['now'] / $result['sum'] * 100) . '%';
            $result['content'] = self::patchContent($result['content']);
            $result['order_status']      = 0;
            $result['order_status_text'] = '剩余名额：';

            if ($find) {
                $result['order_status'] = $find['status'];
                $result['order_id']     = $find['id'];
                if ($find['status'] == 1) $result['order_status_text'] = '您已报名，等待商家确认';
                if ($find['status'] == 2) $result['order_status_text'] = '请准时到岗并打卡哦';
            }

            $this->success('获取成功', $result);
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 兼职报名
     * 判断兼职状态,用户状态,实名认证,是否已经报名
     */
    public function enroll()
    {
        if ($this->request->isGet()) {

            $id = $this->request->param('id', false);
            $id == false && $this->error('id 参数不得为空');
            $this->auth->status == 2 && $this->error('您的账号已被禁用，请及时联系客服人员处理！');
            $this->auth->real == 2 && $this->error('报名失败，请先去实名认证', null, 2);


            // 验证招聘
            $find_job = Db::name('job')->field('id,status,job_company_id,hotel_id,job_type,job_date,job_time_hour,job_price,job_people,job_number')->find(['id' => $id]);
            if ($find_job) {
                $find_job['status'] != 2 && $this->error('报名失败，该招聘不在报名状态');

                // 验证用户是否已经报名
                $find_order = Db::name('order')->where(['user_id' => $this->auth->id, 'status' => 1])->find();
                $find_order && $this->error('报名失败，您已报名其他岗位，请先去取消报名！');

                // 验证是否被延顺
                $find_shun = Db::name('order')->where(['user_id' => $this->auth->id, 'status' => 2, 'is_renewal' => 1, 'order_job_type' => $find_job['job_date']])->find();
                $find_shun && $this->error('报名失败，该岗位上班时间，您已被顺延');

                // 验证招聘是否已经报满
                $find_job['job_number'] >= $find_job['job_people'] && $this->error('报名失败，该招聘已经报满');

                // 不能重复报名同一个招聘
                $s = Db::name('order')->where(['user_id' => $this->auth->id, 'job_id' => $id])->find();
                $s && $this->error('报名失败，不能重复报名同一个岗位');
            } else {
                $this->error('报名失败，未找到招聘信息');
            }

            try {
                Db::startTrans();

                // 插入订单
                $result = Db::name('order')->insert([
                    'user_id'         => $this->auth->id,
                    'number'          => time() . rand(10000, 99999),
                    'hotel_id'        => $find_job['hotel_id'],
                    'job_id'          => $find_job['id'],
                    'company_id'      => $find_job['job_company_id'],
                    'user_mobile'     => $this->auth->mobile,
                    'order_job_type'  => $find_job['job_type'],
                    'order_job_date'  => $find_job['job_date'],
                    'time_hour'       => $find_job['job_time_hour'],
                    'price'           => $find_job['job_price'],
                    'confirm_renewal' => 1,
                    'createtime'      => time(),
                    'updatetime'      => time(),
                    'status'          => 1,
                ]);
                if ($result == 0) {
                    Db::rollback();
                    $this->error('报名失败，新增数据失败');
                }

                // 调整兼职表报名人数
                $result = Db::name('job')->where(['id' => $id])->setInc('job_number');
                if ($result == 0) {
                    Db::rollback();
                    $this->error('报名失败，调整兼职表数据失败');
                }

                Db::commit();
                $this->success('报名成功');
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 取消报名
     */
    public function cancel()
    {
        if ($this->request->isGet()) {

            $id = $this->request->param('id', false);
            $id == false && $this->error('id 参数不得为空');

            // 判断id和请求者的关系
            $find_order = Db::name('order')->where(['id' => $id, 'user_id' => $this->auth->id])->find();
            !$find_order && $this->error('取消失败，不能取消别人的订单');

            try {
                Db::startTrans();

                // 删除订单
                $result = Db::name('order')->delete(['id' => $id]);
                if ($result == 0) {
                    Db::rollback();
                    $this->error('取消失败，删除数据失败');
                }

                // 调整兼职表报名人数
                $result = Db::name('job')->where(['id' => $find_order['job_id']])->setDec('job_number');
                if ($result == 0) {
                    Db::rollback();
                    $this->error('取消失败，调整兼职表数据失败');
                }

                Db::commit();
                $this->success('取消成功');
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        } else {
            $this->error(ErrorCode::$ERROR['ERROR_METHOD']);
        }
    }

    /**
     * 获取指定时间的周次, 默认返回当前日期的周次
     * @param null $time
     * @return false|string
     */
    private function getWeek($time = null)
    {
        if (is_null($time)) $time = date('Y-m-d');

        $week = date("N", strtotime($time));
        switch ($week) {
            case 1:
                $week = "周一";
                break;
            case 2:
                $week = "周二";
                break;
            case 3:
                $week = "周三";
                break;
            case 4:
                $week = "周四";
                break;
            case 5:
                $week = "周五";
                break;
            case 6:
                $week = "周六";
                break;
            case 7:
                $week = "周日";
                break;
        }
        return $week;
    }
}